use actix_web::{error, post, web, App, Error, HttpResponse, HttpServer, Result, get};
use futures::StreamExt;
use serde::{Deserialize, Serialize};
use serde::__private::de::borrow_cow_bytes;

#[derive(Deserialize)]
struct Info {
    username: String,
}

// 使用web::Json只需要serde依赖即可
async fn index(info: web::Json<Info>) -> Result<String> {
    Ok(format!("Welcome {}!", info.username))
}

#[derive(Serialize, Deserialize)]
struct MyObj {
    name: String,
    number: i32,
}

const MAX_SIZE: usize = 262_144;

// 使用提取器需要serde_json和futures依赖
#[post("/")]
async fn index_manual(mut payload: web::Payload) -> Result<HttpResponse, Error> {
    let mut body = web::BytesMut::new();
    while let Some(chunk) = payload.next().await {
        let chunk = chunk?;
        if (body.len() + chunk.len()) > MAX_SIZE {
            return Err(error::ErrorBadRequest("overflow"));
        }
        body.extend_from_slice(&chunk);
    }

    let obj = serde_json::from_slice::<MyObj>(&body)?;
    Ok(HttpResponse::Ok().json(obj))
}

#[derive(Deserialize)]
struct FormData{
    username: String
}

// web::Form有如下限制:
// content-type必须为application/x-www-form-urlencoded
// 传输编码不能为chunked
// 内存长度不能大于256k
#[post("/index2")]
async fn index2(form : web::Form<FormData>)->HttpResponse{
    HttpResponse::Ok().body(format!("username: {}",form.username))
}


// 流媒体
#[get("/index3")]
async fn index3(mut body: web::Payload)->Result<HttpResponse,Error>{
    let mut bytes = web::BytesMut::new();
    // 逐块读取并打印
    while let Some(item) = body.next().await {
        let item = item?;
        println!("Chunk: {:?}", item);
        bytes.extend_from_slice(&item);
    }

    Ok(HttpResponse::Ok().finish())
}

// 文件上传需要依赖三方库,示例地址: https://github.com/actix/examples/tree/master/forms/multipart

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().route("/", web::post().to(index)))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}
